/**
 * @file myfind.c
 * Betriebssysteme Myfind File
 * Beispiel 1
 *
 * @author ic14b065 Franz Passecker <franz.passecker@technikum-wien.at>
 * @author ic14b502 Dominik Starlinger
 * @author ic14b503 Patrick Svaton
 * @date 2015/03/13
 *
 * @version 1.0
 *
 * @todo main		    works
 * @todo do_dir		    works
 * @todo do_file	    works
 * @todo do_ls		    works
 * @todo user	    works
 * @todo nouser	    works
 * @todo type	    works
 * @todo name	    works
 * @todo path	    works
 * @todo check_parms	    works
 * @todo print_help 	    works
 * @todo print	            works
 *
 * Last Modified: Dominik
 *
 */

/*
 * -------------------------------------------------------------- includes --
 */
#include <stdio.h>      /*standard input output library for C*/
#include <stdlib.h>     /*standard functions library for C*/
#include <string.h>     /*includes functions for string handling*/
#include <dirent.h>	/*includes functions to go through directories (i.e. opendir, closedir,...)*/
#include <limits.h>	/*includes limits for maximum path- and file-lengths*/
#include <errno.h>	/*includes definitions for C Error Codes*/
#include <sys/stat.h>	/*defines the structure of the data returned by the functions fstat(), lstat(), and stat()*/
#include <sys/types.h>  /*defines used data types*/
#include <pwd.h>	/*includes password structures, needed to check for users*/
#include <grp.h>        /*declares structure group and some functions*/
#include <time.h>       /*includes functions for date and time*/
#include <fnmatch.h>	/*includes function to match filename or pathname*/

/*
 * --------------------------------------------------------------- defines --
 */


/*
 * -------------------------------------------------------------- typedefs --
 */


/*
 * --------------------------------------------------------------- globals --
 */


/*
 * ------------------------------------------------------------- functions --
 */
int do_file(const char *file_name, const char * const *parms);
int do_dir(const char *dir_name, const char * const *parms);
int do_ls(const struct stat* file_info, const char *file_name);
int do_type(char* type, const char * const *options);
int check_parms(const char * const *parms);
int check_parms_user(const char *user);
int check_parms_type(const char *type);
void print_help(void);
int check_file(const struct stat* file_info, char type, int type_counter, char *user, int no_user, int user_counter, int name_ok, int path_ok);
char get_mode(mode_t mode);
int is_numeric(const char *user);
int get_uid(const char *user);

/**
 *
 * \brief Myfind(1) a simplified version of find(1)
 *
 * This is the main entry point for any C program.
 *
 * \param argc the number of arguments
 * \param argv the arguments itselves (including the program name in argv[0])
 *
 * \return EXIT_SUCCESS or EXIT_FAILURE
 * \retval 0 or 1
 *
 */

/* ### FB: Fehlerbehandlung fprintf stdout fehlt. */
int main(int argc, const char * const *argv)
{
	int errVar = EXIT_SUCCESS;	/*errorvariable reset to success, if any error is detected set to failure*/
	char *directory = ".";

	if(argc<=1)	/*no parameters given, begin with current directory*/
	{
		/* ### FB: in der "Referenzversion" wird die Hilfe ausgegeben, wenn keine Parameter übergeben wurden. */
		if((errVar=do_file(directory, argv)))	/*if do_file returns 1, error occured*/

		{
			fprintf(stdout,"%s: Error Message = myfind cannot run on current directory.\n", argv[0]);
			errVar = EXIT_FAILURE;
		}
	}
	else		/*parameters are given*/
	{
		errVar = check_parms(argv);  /*check given parameters on consistency*/

		if(errVar==EXIT_SUCCESS)
		{
		  /* ### FB: Laut Angabe ist der Pfad als 1. Argument verpflichtend @Markus Richtig in Bezug auf find, falsch bzgl. Angabe */

			if(strncmp("-",argv[1],1)==0)	/*if first param is argument, start myfind in current directory*/
			{
				errVar=(do_file(directory,argv));
			}
			else				            /*else use the given path*/
			{
				errVar=(do_file(argv[1], argv));
			}
		}
	}

	return errVar;
}


/**
 *
 * \brief do_dir opens directories and print them to console
 *
 * \param dir_name gives name and path of starting directory
 * \param parms gives arguments (also found in argv)
 *
 * \return EXIT_SUCCESS or EXIT_FAILURE
 * \retval 0 or 1
 *
 */

int do_dir(const char *dir_name, const char * const *parms)
{
	struct dirent *start = NULL;    /*file serial number and file name*/
	struct stat file;   		    /*information about file*/
	char *path = NULL;	    	    /*variable for path*/
	DIR *dir_p = NULL;	    	    /*structure for directory path*/
	int path_len = 0;	    	    /*current pathlength*/
	int errVar = EXIT_SUCCESS;	    /*errorvariable reset to success, if any error is detected set to failure*/

	/*checks if their is a directory given or not*/
	if((dir_p = opendir(dir_name)) == NULL)	/*if not, no further dir, maybe file?*/
	{
		fprintf(stderr,"%s: Directory Error Message = %s\n", parms[0], strerror(errno));
		if(closedir(dir_p))
		{
			fprintf(stderr,"%s: Directory Error message = %s\n", parms[0], strerror(errno));
			errVar = EXIT_FAILURE;
		}
	}

	/*dir could be open*/
	else
	{
		/*go through all subdirs and files in current dir_name*/
		while((start=readdir(dir_p))!=0 && errVar==EXIT_SUCCESS)
		{
			if(strcmp(start->d_name,".")!=0 && (strcmp(start->d_name,"..")!=0))	/*exception for own dir and upleading dir*/
			{
				/*checking path, alloc space and build path*/
				if((strlen(start->d_name) + 1) > NAME_MAX)
				{
					fprintf(stderr,"%s: name of path too long\n", parms[0]);
					errVar = EXIT_FAILURE;
				}
				else
				{
					path_len = strlen(dir_name) + strlen(start->d_name) + 2; /*get Pathlength from pathname + 2 (because of '/' and '\0')*/
					if((path = malloc(path_len * sizeof(char))) == NULL)	/*malloc already in stdlib.h included*/
					{
						fprintf(stderr,"%s: Cannot allocate space for pathname\n", parms[0]);
						errVar = EXIT_FAILURE;
					}
					else
					{
						path[0] = '\0';			    	/*path = '\0' */
						strcat(path,dir_name);			/*path = 'dir_name\0' */

						if(path[strlen(path)-1] != '/')	/*check if path is already ended with '/' */
						{
							strcat(path,"/");	    	/*if not attach it to path = 'dir_name/\0' */
						}

						strcat(path,start->d_name);		/*attach current dir to the path = 'dir_name/d_name\0'*/

						/*check if built path points at valid file*/
						if(lstat(path, &file) < 0)	/*stat gives information about the path an writes to buf=file*/
						{
							fprintf(stderr,"%s: File Error Message = %s\n", parms[0], strerror(errno));
							errVar = EXIT_FAILURE;
						}
						else
						{
							/*do file or path*/
							errVar = do_file(path,parms);
						}
					}

					if(path != NULL)	/*free allocated space for path (malloc!)*/
					{
						free(path);
						path = NULL;
					}

				}
			}
		}
	}


	if(closedir(dir_p))
	{
		fprintf(stderr,"%s: Directory Error Message = %s\n", parms[0], strerror(errno));
		errVar = EXIT_FAILURE;
	}
	return errVar;
}


/**
 *
 * \brief do_file checks file data and print it depending on parms
 *
 * \param file_name gives name and path of starting directory
 * \param parms gives arguments (also found in argv)
 *
 * \return EXIT_SUCCESS or EXIT_FAILURE
 * \retval 0 or 1
 *
 */
/* ###FB: Funktion etwas lang und verschachtelt - aufteilen auf einzelne funktionen für parameter würde es übersichtlicher machen. */
int do_file(const char *file_name, const char * const *parms)
{
	struct stat buf;	        /*information about file*/
	int errVar = EXIT_SUCCESS;	/*errorvariable reset to success, if any error is detected set to failure*/
	int print = 0;			/*check if parameters include -print or -ls*/
	const char * const *parameters = parms; /* save parameters to start next do_dir */
	char *parameter = NULL;	/*specific parameter used for further treatment*/
	int no_user = 0; 		/*nouser at start not active*/
	char *user = NULL;		/*variable for username or UID*/
	char type = '\0';		/*variable for type*/
	int type_counter = 0;	/*variable for type as set parameter*/
	int user_counter = 0;	/*variable for user as set parameter*/
	int name_ok = 1;		/*will be set to zero if name pattern isn't valid*/
	int path_ok = 1;		/*will be set to zero if path pattern isn't valid*/

	if(lstat(file_name, &buf) < 0)	/*writing information from given file_name to file*/
	{
		fprintf(stderr,"%s: File Error Message = %s\n", parms[0], strerror(errno));
		errVar = EXIT_FAILURE;
	}
	else	/*check parms and print file attributes if needed*/
	{
		parms++;

		while(*parms != NULL)
		{
			/*checks if further actions are needed for particular file*/
			if (check_file(&buf, type, type_counter, user, no_user, user_counter, name_ok, path_ok) == 0)
			{
				break;
			}

			/*parameter -ls is active*/
			if(strcmp(*parms,"-ls") == 0)		/*print more infos of file*/
			{
				print = 1;
				if(do_ls(&buf, file_name) != 0)
				{
					errVar = EXIT_FAILURE;
					break;
				}
			}

			/*parameter -user is active*/
			else if(strcmp(*parms,"-user") == 0)	/*print files of particular user*/
			{
				parms++;
				if(user == NULL)
				{
					if((user = malloc(sizeof(*parms))) == NULL)
					{
						errVar = EXIT_FAILURE;
						break;
					}
				}

				if(get_uid(user) != get_uid(*parms))
				{
					user_counter++;
					strcpy(user, *parms);
				}
			}

			/*parameter -nouser is active*/
			else if(strcmp(*parms,"-nouser") == 0)	/*print files with no user*/
			{
				if(no_user == 0)
				{
					user_counter++;
					no_user = 1;
				}
			}

			/*parameter -type is active*/
			else if(strcmp(*parms,"-type") == 0)	/*print files with particular type*/
			{
				parms++;
				if(type != *parms[0])
				{
					type_counter++;
					type = *parms[0];
				}
			}

			/*parameter -name is active*/
			else if(strcmp(*parms,"-name") == 0)	/*print files with particular name*/
			{

				parms++;

				if((parameter = malloc(sizeof(file_name))) == NULL)
				{
					errVar = EXIT_FAILURE;
					break;
				}

				if(strstr(file_name, "/"))
				{
					parameter = strrchr(file_name, '/');
					parameter++;
				}
				else
				{
					strcpy(parameter, file_name);
				}

				if(fnmatch(*parms, parameter, FNM_NOESCAPE) != 0)
				{
					name_ok = 0;
				}
			}

			/*parameter -path is active*/
			else if(strcmp(*parms,"-path") == 0)	/*print files with particular path*/
			{
				parms++;

				if(fnmatch(*parms, file_name, FNM_NOESCAPE) != 0)
				{
					path_ok = 0;
				}

			}



			/*parameter -print is active*/
			else if(strcmp(*parms,"-print") == 0)	/*print name of directory*/
			{
				print = 1;
				fprintf(stdout, "%s\n", file_name);
			}

			parms++;
		}

		if(print == 0 && check_file(&buf, type, type_counter, user, no_user, user_counter, name_ok, path_ok) != 0)
		{
			fprintf(stdout, "%s\n", file_name);
		}

		/*check if directory*/
		if((buf.st_mode & S_IFMT) == S_IFDIR)
		{
			do_dir(file_name, parameters);
		}

		free(user);
	}

	return errVar;
}

/**
 *
 * \brief check_file finds out if file should be handled further under do_file
 *
 * \param file_info structure with attributes of the file
 * \param type variable for types
 * \param type_counter variable
 * \param user variable for userid's
 * \param no_user variable for files without user
 * \param user_counter variable foe files with user
 * \param name_ok is zero if name pattern isn't valid
 * \param path_ok is zero if path pattern isn't valid
 *
 * \return 0 or 1
 * \retval 0 or 1
 *
 */
int check_file(const struct stat* file_info, char type, int type_counter, char *user, int no_user, int user_counter, int name_ok, int path_ok)
{
	mode_t mode = file_info->st_mode;	/*stores mode of given file*/

	/*check if the user gives to many type or user parameters, so that no valid value is possible*/
	if (type_counter > 1 || user_counter > 1 || name_ok == 0 || path_ok == 0)
	{
		return 0;
	}

	if(type == get_mode(mode) || type == '\0' || (type == 'f' && get_mode(mode) == '-'))
	{
		if(user_counter == 1)
		{
			if(no_user == 1)
			{
				if(getpwuid(file_info->st_uid) == NULL)
				{
					return 1;
				}
			}
			else
			{
				int uid = get_uid(user);

				if((uid_t) uid == file_info->st_uid)
				{
					return 1;
				}
			}
		}
		else
		{
			return 1;
		}
	}

	return 0;
}

/**
 *
 * \brief get_uid returns the given user-pattern as UID
 *
 * \param user contains given user pattern
 *
 * \return uid
 *
 */

int get_uid(const char *user)
{
	int uid = 0;	/*numeric UID*/
	char *succ = NULL;	/*pointer for the beginn of the numeric UID in given string*/
	struct passwd *pPwdEntry = NULL;	/*data structure containing user account information*/

	if((pPwdEntry = getpwnam(user)) != NULL)
	{
		uid = pPwdEntry->pw_uid;
	}
	else
	{
		int isnumeric = is_numeric(user);
		if(isnumeric == 1)
		{	/* ###FB: bei der Verwendung von strtol sollte auf errno Rücksicht genommen werden. */
			uid = strtol(user, &succ, 10); /*changes user in UID*/
		}
	}

	return uid;
}

/**
 *
 * \brief do_ls prints further information to a file or directory: inode-number, block-count, permissions, link-count, owner, group, last modification time, directoryname and if sym-link the target.
 *
 * \param file_info structure with attributes of the file
 * \param file_name gives name and path of starting directory
 *
 * \return EXIT_SUCCESS or EXIT_FAILURE
 * \retval 0 or 1
 *
 */
/* ###FB: Fehlerbehandlung fprintf, sprintf, strftime fehlt. */
int do_ls(const struct stat* file_info, const char *file_name)
{
	int errVar = EXIT_SUCCESS;	/*errorvariable reset to success, if any error is detected set to failure*/
	char rights[11];		/*rights of the file*/
	int size = file_info->st_blocks/2;			/*number of blocks allocated divided by  2*/
	struct passwd *pPwdEntry = NULL;	/*data structure containing user account information*/ 
	struct group *pGrpEntry = NULL;	/*data structure containing group information*/
	/* ###FB: die hardcoded numbers könnten durch #defines ersetzt werden */
	char groupname[255];
	char username[255];
	char date[80];
	struct tm filetime;
	/* ###FB: pointer mit NULL initialisieren. */
	struct tm * actualtime;
	time_t rawtime;
	mode_t mode = file_info->st_mode;

	time(&rawtime);
	actualtime = localtime(&rawtime);
	localtime_r(&file_info->st_mtime, &filetime);

	/* Post year if file is older thant 182 days else post the time*/
	/* ###FB: hardcoded "182" könnte durch #define ersetzt werden */
	if(((filetime.tm_yday-actualtime->tm_yday) >= -182 && (filetime.tm_yday-actualtime->tm_yday) <= 182 && (filetime.tm_year+1) == actualtime->tm_year) || ((filetime.tm_year+2) <= actualtime->tm_year))
	{
		strftime(date, sizeof(date), "%b", &filetime);
		sprintf(date, "%s %2d  %4d", date, filetime.tm_mday, (filetime.tm_year+1900));
	}
	else
	{

		strftime(date, sizeof(date), "%b", &filetime);
		sprintf(date, "%s %2d %02d:%02d", date, filetime.tm_mday, filetime.tm_hour, filetime.tm_min);
	}

	/*get owner name*/
	if((pPwdEntry = getpwuid(file_info->st_uid)) == NULL)
	{
		sprintf(username, "%d", file_info->st_uid);
	}
	else
	{
		strcpy(username, pPwdEntry->pw_name);
	}

	/*get groupname*/
	if((pGrpEntry = getgrgid(file_info->st_gid)) == NULL)
	{
		sprintf(groupname, "%d", file_info->st_gid);
	}
	else
	{
		strcpy(groupname, pGrpEntry->gr_name);
	}

	rights[0] = get_mode(mode);
	rights[1] = (mode & S_IRUSR) ? 'r' : '-';
	rights[2] = (mode & S_IWUSR) ? 'w' : '-';
	rights[3] = ((mode & S_IXUSR) && (mode & S_ISUID)) ? 's' : (mode & S_ISUID) ? 'S' : (mode & S_IXUSR) ? 'x' : '-';
	rights[4] = (mode & S_IRGRP) ? 'r' : '-';
	rights[5] = (mode & S_IWGRP) ? 'w' : '-';
	rights[6] = ((mode & S_IXGRP) && (mode & S_ISGID)) ? 's' : (mode & S_ISGID) ? 'S' : (mode & S_IXGRP) ? 'x' : '-';
	rights[7] = (mode & S_IROTH) ? 'r' : '-';
	rights[8] = (mode & S_IWOTH) ? 'w' : '-';
	rights[9] = ((mode & S_IXOTH) && (mode & S_ISVTX)) ? 't' : (mode & S_ISVTX) ? 'T' : (mode & S_IXOTH) ? 'x' : '-';
	rights[10] = '\0';
	fprintf(stdout,"%6lu %4d %s %3lu %-8s %-8s %8lu %s %s\n", file_info->st_ino, size, rights, (unsigned long) file_info->st_nlink, username, groupname, file_info->st_size, date, file_name);
	/* ### FB errVar wird in do_ls nicht verändert - unnötig? */
	return errVar;
}

/**
 *
 * \brief get_mode returns type of given file
 *
 * \param mode stores boolean values for file type
 *
 * \return type
 * \retval b or c or p or - or d or l or s or u
 *
 */
 
char get_mode(mode_t mode)
{
	char type;

	switch(mode & S_IFMT) {
	case S_IFBLK:
		type = 'b';
		break;
	case S_IFCHR:
		type = 'c';
		break;
	case S_IFIFO:
		type = 'p';
		break;
	case S_IFREG:
		type = '-';
		break;
	case S_IFDIR:
		type = 'd';
		break;
	case S_IFLNK:
		type = 'l';
		break;
	case S_IFSOCK:
		type = 's';
		break;
	default:
		type = 'u';
		break;
	}

	return type;

}


/**
 *
 * \brief check_parms_user if user is existent/valid
 *
 * \param user stores given user pattern
 *
 * \return EXIT_SUCCESS or EXIT_FAILURE
 * \retval 0 or 1
 *
 */

int check_parms_user(const char *user)
{
	int errVar = EXIT_SUCCESS;	/*errorvariable reset to success, if any error is detected set to failure*/
	int uid = 0;		/*needed to check both: username or userID*/
	char *succ = NULL;	/*needed for strtol*/
	int isnumeric = is_numeric(user);	/*gives info if userpattern is numeric or non-numeric*/


	if(getpwnam(user)!=NULL)	/*if user is written as username*/
	{
		errVar=EXIT_SUCCESS;
	}
	else	/*checks if user is written as UID*/
	{
		if(isnumeric == 1)
		{	/* ###FB: bei der Verwendung von strtol sollte auf errno Rücksicht genommen werden. */
			uid = strtol(user, &succ, 10);	/*changes user in UID*/
			if((getpwuid((uid_t) uid)==NULL))
			{
				errVar = EXIT_FAILURE;	/*UID is not valid*/
			}
		}
		else
		{
			errVar = EXIT_FAILURE; /*UID is not numeric*/
		}
	}

	return errVar;
}


/**
 *
 * \brief is_numeric checks if user pattern is numeric or not
 *
 * \param user stores given user pattern
 *
 * \return EXIT_SUCCESS or EXIT_FAILURE
 * \retval 0 or 1
 *
 */

int is_numeric(const char *user)
{
	int length = strlen(user);
	int i = 0;
	int isnumeric = 1;	/*set to zero if not numeric*/

	for(i = 0; i < length; i++) {
		if(((int)user[i])<48 || ((int)user[i])>57)
		{
			isnumeric = 0;
		}
	}

	return isnumeric;
}


/**
 *
 * \brief check_parms checks if given parameters are allowed or not
 *
 * \param parms char with all given parameters to myfind
 *
 * \return EXIT_SUCCESS or EXIT_FAILURE
 * \retval 0 or 1
 *
 */

int check_parms(const char * const *parms)
{
	int errVar = EXIT_SUCCESS;	/*errorvariable reset to success, if any error is detected set to failure*/
	int i=1;		         	/*iteration variable for counting the given parameters to check*/

	while(parms[i] != NULL)
	{
		/*0.) check if -help is called*/
		/*1.) check if the path is the first parameter*/
		/*2.) check out the given parameters on consistency*/
		/*3.) check pattern of parameters*/

		if(strcmp(parms[i],"-help")==0)
        	{	/* 
			 *###FB: print_help() wird nur aufgerufen, wenn als parameter -help uebergeben 
			 *	 wurde und dann läuft der myfind einmal mit directory "." durch.
			 *	 Ueberlegung ob sinnvoll? Parameter "-help" ist lt. Angabe nicht definiert und auch im "Originalen" find
			 *	 läuft "find" nicht, wenn "-help" übergeben wird. (Auch wenn andere Paramter dabei sind.)
			 *	 Evtl. mit EXIT_SUCCESS beenden? 
			 */				
            		print_help();
            		break;
        	}

		if(strcmp(parms[i],"-ls")==0 ||
			strcmp(parms[i],"-nouser")==0 ||
			strcmp(parms[i],"-print")==0 ||
			strcmp(parms[i],"-help")==0)	/*arguments without pattern*/
		{
			if(parms[i+1] != NULL)
			{
				/* ### FB: selbe Abfrage ein paar Zeilen weiter unten, nur verneint --> haette ausgelagert werden koennen */
				if(strcmp(parms[i+1],"-ls")!=0 &&
					strcmp(parms[i+1],"-user")!=0 &&
					strcmp(parms[i+1],"-nouser")!=0 &&
					strcmp(parms[i+1],"-type")!=0 &&
					strcmp(parms[i+1],"-name")!=0 &&
					strcmp(parms[i+1],"-path")!=0 &&
					strcmp(parms[i+1],"-print")!=0 &&
					strcmp(parms[i+1],"-help")!=0)	/*checks if path follows arguments without pattern*/
				{
					errVar = EXIT_FAILURE;
					fprintf(stderr, "%s: Error Message = given path has to lead parameters\n", parms[0]);
					break;
				}
			}
		}
		else if(strcmp(parms[i],"-user")==0 ||
			strcmp(parms[i],"-type")==0 ||
			strcmp(parms[i],"-name")==0 ||
			strcmp(parms[i],"-path")==0)	/*arguments with pattern*/
		{
			if(parms[i+1]!=NULL)	/*checks if there are parms behind arguments with pattern*/
			{
				/* ### FB: selbe Abfrage ein paar Zeilen weiter oben, nur nicht verneint --> haette ausgelager werden koennen */
				if(strcmp(parms[i+1],"-ls")==0 ||
					strcmp(parms[i+1],"-user")==0 ||
					strcmp(parms[i+1],"-nouser")==0 ||
					strcmp(parms[i+1],"-type")==0 ||
					strcmp(parms[i+1],"-name")==0 ||
					strcmp(parms[i+1],"-path")==0 ||
					strcmp(parms[i+1],"-print")==0 ||
					strcmp(parms[i+1],"-help")==0)	/*checks if arguments with pattern has actual a pattern*/
				{
					errVar = EXIT_FAILURE;
					fprintf(stderr, "%s: Error Message = '%s' needs an argument\n", parms[0], parms[i]);
					break;
				}
				else	/*checks if pattern of arguments with pattern is consistent*/
				{
					if(strcmp(parms[i],"-user")==0)
					{
						if(check_parms_user(parms[i+1])!=0)	/*checks if given username is valid*/
						{
							errVar = EXIT_FAILURE;
							fprintf(stderr, "%s: Error Message = '%s' is an invalid argument to '%s'\n", parms[0], parms[i+1], parms[i]);
							break;
						}
					}
					else if(strcmp(parms[i],"-type")==0)
					{
						if(check_parms_type(parms[i+1])!=0)	/*checks if given typeis valid*/
						{
							errVar = EXIT_FAILURE;
							fprintf(stderr, "%s: Error Message = '%s' is an invalid argument to '%s'\n",parms[0], parms[i+1], parms[i]);
							break;
						}
					}
					i++;	/*count +1 for pattern*/
				}
			}
			else
			{
				errVar = EXIT_FAILURE;
				fprintf(stderr, "%s: Error Message = '%s' needs an argument\n", parms[0], parms[i]);
				break;
			}
		}
		else if(strncmp(parms[i],"-",1)==0)
		{
			errVar = EXIT_FAILURE;
			fprintf(stderr, "%s: Error Message = invalid prefix in '%s'\n", parms[0], parms[i]);
			break;
		}
		else if((i!=1) && strncmp(parms[i],"-",1) != 0)
		{
			errVar = EXIT_FAILURE;
			fprintf(stderr, "%s: Error Message = path have to be before the parameters\n", parms[0]);
		}
		i++;	/*count +1 for next parameter*/
	}

	return errVar;
}


/**
 *
 * \brief check_parms_type checks if type pattern is valid
 *
 * \param type stores searched type pattern
 *
 * \return EXIT_SUCCESS or EXIT_FAILURE
 * \retval 0 or 1
 *
 */

int check_parms_type(const char *type)
{
	int errVar = EXIT_SUCCESS;	/*errorvariable reset to success, if any error is detected set to failure*/

	/*### FB: da es sich hier um characters handelt, ist strcmp nicht notwendig. */
	if(strcmp(type,"f")==0 ||		/*Regular File*/
		strcmp(type,"d")==0 ||		/*Directory*/
		strcmp(type,"l")==0 ||		/*Symbolic Link*/
		strcmp(type,"p")==0 ||		/*Named Pipe*/
		strcmp(type,"s")==0 ||		/*Local Domain Socket*/
		strcmp(type,"b")==0 ||		/*Block Device*/
		strcmp(type,"c")==0)		/*Character Device*/
		return errVar;
	else errVar = EXIT_FAILURE;

	return errVar;
}


/**
 *
 * \brief print_help prints help to myfind
 *
 * \return void
 *
 */
    
    /* ### FB: Fehlerbehandlung fprintf fehlt. */
void print_help()
{
	fprintf(stdout,"Usage: myfind <path> [arguments]\n");
	fprintf(stdout,"Arguments: -ls\n");
	fprintf(stdout,"           -user <username|userid>\n");
	fprintf(stdout,"           -nosuer\n");
	fprintf(stdout,"           -type <type>\n");
	fprintf(stdout,"           -name <namepattern>\n");
	fprintf(stdout,"           -path <pathpattern>\n");
	fprintf(stdout,"           -print\n");
	fprintf(stdout,"           -help\n");
}
